<?php
/**
 * DtsService.php
 * Author: K
 * Date: 2023/10/10 09:55
 */

namespace app\api\services;

use app\api\model\DtsGame;
use app\api\model\User as UserModel;
use think\cache\driver\Redis;

class DtsService
{

    /**
     * 人数最低限制
     * @var int
     */
    public static $max_people = 2;

    /**
     * 倒计时秒数
     * @var int
     */
    public static $duration = 10;

    /**
     * @var DtsService
     */
    private static $instance;

    public static function getInstance()
    {
        if (self::$instance) {
            return self::$instance;
        }
        $redis = new Redis(['select' => 7]);
        self::$instance = $redis;
        return self::$instance;
    }

    public static function updateBonus(UserModel $user, DtsGame $game, $bonus)
    {
        $redis = self::getInstance();
        $key = sprintf('dtsgame:user_list:%s', $game->id);
        $data = $redis->hget($key, $user->id);
        $data = json_decode($data);

        $data->bonus = $bonus;
        $redis->hset($key, $user->id, json_encode($data));
    }

    public static function joinGame(UserModel $user, DtsGame $game, $room_id = 0, $amount = 0): void
    {
        $redis = self::getInstance();
        $key = sprintf('dtsgame:user_list:%s', $game->id);

        $data = [
            'userId'  => $user->id,
//            'nickname' => mb_substr($user->name, 0, 3) . '*',
            'nickName' => $user->nickName,
            'index'  => $room_id,
            'costInputAmount'   => $amount,
        ];
        $redis->hset($key, $user->id, json_encode($data));
    }

    public static function exist($game_id, $user_id)
    {
        $redis = self::getInstance();
        $key = sprintf('dtsgame:user_list:%s', $game_id);
        return $redis->hexists($key, $user_id);
    }

    public static function removeGameUserList(UserModel $user, DtsGame $game): void
    {
        $redis = self::getInstance();
        $key = sprintf('dtsgame:user_list:%s', $game->id);
        $redis->hdel($key, $user->id);
    }

    public static function getGameUserList(DtsGame $game): array
    {
        $redis = self::getInstance();
        $key = sprintf('dtsgame:user_list:%s', $game->id);
        $data = $redis->hgetall($key);

        return array_values(array_map(function ($value) {
            return json_decode($value, true);
        }, $data));
    }

    public static function getGameUserBettingList($user_list): array
    {
        return array_filter($user_list, function ($value) {
            if ($value && $value['index']) {
                return $value;
            }
        });
    }

    public static function deleteGameCache(DtsGame $game): void
    {
        $redis = self::getInstance();
        $key = sprintf('dtsgame:user_list:%s', $game->id);
        $redis->delete($key);
    }


    public static function calcLastWeekRank($limit = 10)
    {
        return UserModel::where('dts_dress', 0)
            ->field('id,avatarUrl,nickName')
            ->withSum(['dtsRank' => 'amount'], 'bonus')
            ->order('amount', 'desc')
            ->limit($limit)
            ->select()->toArray();
    }

    public static function getUserGameData(DtsGame $game, $user_id)
    {
        $redis = self::getInstance();
        $key = sprintf('dtsgame:user_list:%s', $game->id);
        $data = $redis->hget($key, $user_id);
        $data = json_decode($data);
        return $data;
    }


    public static function calcRoomAmount(array $user_list): array
    {
        $data = [];
        for ($i = 1; $i <= 8; $i++) {
            $amount = 0;
            foreach ($user_list as $item) {
                if ($item && $item['index'] == $i) {
                    $amount += $item['costInputAmount'];
                }
            }
            $data[] = [
                'index' => $i,
                'costInputAmount'  => $amount
            ];
        }
        return $data;
    }

    public static function updateGame(DtsGame $game)
    {
        $duration = self::$duration;
        $limit_people = self::$max_people;
        if ($game->state != 1) {
//            $this->debugInfo('结算倒计时' . ($game->end_time - time()));
            return;
        }
        $total = $game->records()->count();
        if ($total >= $limit_people) {
//            $this->debugInfo(sprintf('================== game【%s】开始结算 ==================', $game->id));
            $game->state = 2;
            $game->start_time = time();
            $game->end_time = $game->start_time + $duration;
            $game->save();
        }
    }

}